<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>我们要不要上线「个人app」 ？ | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6auy000g7kny4wjh1gbc" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      我们要不要上线「个人app」 ？
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-10-06T17:10:49.000Z" itemprop="datePublished">2020-10-07</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <p>我个人对于新事物抱着总是乐于尝试的态度，可能是小时候能够接触的东西太少。目前情况下，在自己的承受或者精力范围内，会主动去买一些或者做一些东西，更多时候是为了体验一下。我始终认为，很多东西只有亲身去感受，才能深刻的认识到自己对这个东西的见解。</p>
<a id="more"></a>

<p>今天给大家分享下，是否要去制作并且上线一款个人app，重点是上线，相信大家或多或少都制作多一款或者多款app。</p>
<p>上线的目的并不是为了说能挣多少钱…</p>
<p>想要挣钱没那么容易，很难做到。</p>
<p>上线的目的也不是为了给面试官看，我做了一个多么牛逼的app…</p>
<p>这个针对应届生是可以的，不过多数情况下，上线的app很难达到让面试官眼前一亮的感觉…</p>
<p><strong>但是，我仍然鼓励大家去开发一款个人app，然后去尝试上市场的。</strong></p>
<p>为什么呢？</p>
<p>假如你挣钱了咋办…（开个玩笑），不过我身边确实有制作个人app的朋友，app中有会员机制和广告，每年收入还可以的，相当于给自己涨薪了，厚着脸皮要了个本周某日的数据：</p>
<p><img src="http://user-gold-cdn.xitu.io/2018/5/12/163523539e9ec6e8?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<blockquote>
<p>已经向该制作者承诺，不泄露app相关信息。</p>
</blockquote>
<p>当然这个很难做到，如果做到了，那只能恭喜大家躺着挣钱了。不过不希望大家抱着挣钱的目的去做，这样会比较耗费你的精力。</p>
<p>重要的目标还是体验：<strong>从开发-上线-打磨这个过程</strong>。</p>
<p>通过这个过程，你可以得到一些：</p>
<ol>
<li>你可以更好的了解渠道的定义，工作中总是有多渠道的概念，这个时候你会深刻理解；</li>
<li>你需要自己去搞应用内升级、日活检测、crash率修复、三方登录等；</li>
<li>你会了解各个平台对开发者上线app审核的力度，比如你知道某些平台只让企业开发者，某些平台需要软著，某些平台就较为宽泛的管理；</li>
<li>作为自己视野的开阔与谈资；</li>
</ol>
<p>接下来就以个人经验，分享几个上线个人app的注意事项。</p>
<h2 id="集成数据统计sdk"><a href="#集成数据统计sdk" class="headerlink" title="集成数据统计sdk"></a>集成数据统计sdk</h2><p>不但要集成数据统计sdk，还要注意分渠道。不过一般我们个人app上线，并不会有那么多的渠道，例如使用友盟，利用<code>productFlavors</code>和<code>manifestPlaceholders</code>在manifest中注明渠道即可。</p>
<p>数据统计sdk可以帮你：</p>
<ol>
<li>发现crash，很多时候我们设备单一，大多数的crash还是需要用户去帮你测试出来的；</li>
<li>查看每个渠道的数据，这个会帮你发现哪些渠道比较关键，你可以选择首发，或者遇到审核不过的又非优质的渠道，可以稳住。</li>
<li>查看版本分布；</li>
<li>了解新增、每日日活、留存等，如果发现不对劲，可能是最新上线的功能有什么问题。</li>
</ol>
<p><strong>总之，可以帮你更好的打磨和了解你的应用。</strong></p>
<h2 id="集成应用内检测更新"><a href="#集成应用内检测更新" class="headerlink" title="集成应用内检测更新"></a>集成应用内检测更新</h2><p>即每次更新版本，不需要推到市场，用到打开app即可收到应用内更新。</p>
<p>为什么要这个呢？</p>
<p>当我们更新代码后，可以先开启应用内更新，一般情况下非强制，你可以升级一部分用户后关闭，利用这部分用户做一个简单的灰度。当他们使用过程中没有出现崩溃，也没有反馈，你就可以开心的打各个渠道包，上市场了；如果有问题，你还可以及时的修改代码。避免了刚上市场，发现问题，从而又要立即市场更新，而且这个更新是非及时的。</p>
<p>还有个很关键的原因，尤其是针对个人开发者，很多时候，由于各个市场的评估标准不同，你的app可能只在<code>应用宝</code>，<code>百度手机助手</code>，这两个渠道上。那么小米手机的用户，是无法做到后台自动更新的，需要用户哪天手动打开对应的市场，手动更新，这个过程还是相当漫长的。</p>
<p><strong>总之，应用内检测更新，可以帮你更快的完成版本收敛，更好的保证线上app的质量。</strong></p>
<p>其实应用内更新很方便，github上库也比较多，只要有个地方能放置apk的下载链接，接口利用<a target="_blank" rel="noopener" href="http://www.wanandroid.com/tools/mockapi">www.wanandroid.com/tools/mocka…</a>即可。</p>
<p>比如我：</p>
<p><img src="http://user-gold-cdn.xitu.io/2018/5/12/1635236565177e47?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<blockquote>
<p>这属于偷懒的方案。</p>
</blockquote>
<h2 id="一定要有反馈的功能"><a href="#一定要有反馈的功能" class="headerlink" title="一定要有反馈的功能"></a>一定要有反馈的功能</h2><p>反馈这个功能就更关键了，很多时候，你自己一个人测试和使用者的情况是不同；其次，便于收集需求。</p>
<p>你可以利用云服务器，写个简单的接口，能上传文字就行，记得之前我推荐过京东云，很多人购买了，可以利用起来。当然也可以利用类似bomb这样的后端云去做，总之，一定要能够拿到用户的反馈。</p>
<p>亲身体验，个人app大部分需求迭代，都是用户反馈提供的。</p>
<p><strong>反馈让你真正了解到用户的需求和吐槽。</strong></p>
<blockquote>
<p>后续考虑在wanandroid上面，给大家提供一个接收反馈的能力。</p>
</blockquote>
<h2 id="记得加上跳转到市场的能力"><a href="#记得加上跳转到市场的能力" class="headerlink" title="记得加上跳转到市场的能力"></a>记得加上跳转到市场的能力</h2><p>记得app上线了一年多，只有一个好评，恩，我自己评的…尴尬</p>
<p>其实是因为app并没有能够直接跳转到市场的功能，用户评价的可能性太低了。</p>
<p>加上后，几天内就迎来了好几个好评。</p>
<p>这个成本非常低：</p>
<pre><code class="java">#伪代码
String appPkg = context.getPackageName();
Uri uri = Uri.parse(&quot;market://details?id=&quot; + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
</code></pre>
<p>几行代码的就能搞定。</p>
<p>但是，由于个人app的特殊性，大多数情况下，很多市场是上不去的，比如小米对app质量要求比较高，vivo oppo对开发者资质审查太严格。</p>
<p>自带的市场即使跳转过去，也只会显示未收录该应用。</p>
<p>上述代码只能跳转到手机自带的市场，所以情况应该是，提前扫描用户手机中的市场软件，如果包含你上线的渠道市场，则跳转过去：</p>
<pre><code class="java">#伪代码
String appPkg = context.getPackageName();
// 扫描已经安装的市场包名
ArrayList&lt;String&gt; marketPkgs = MarketUtils.queryInstalledMarketPkgs(context);
L.d(&quot;market = &quot; + marketPkgs);
Uri uri = Uri.parse(&quot;market://details?id=&quot; + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
// 指定市场
if (!TextUtils.isEmpty(marketPkg) &amp;&amp; marketPkgs.contains(marketPkg)) &#123;
    intent.setPackage(marketPkg);
&#125;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
</code></pre>
<p><strong>想要好评，就尽可能让好评变得容易。</strong></p>
<h2 id="提供分享的能力"><a href="#提供分享的能力" class="headerlink" title="提供分享的能力"></a>提供分享的能力</h2><p>分享也是很关键的一个功能，正因为，你的app存在的市场比较少，使用者给其他人推荐的时候可能对方并不能在自带的市场搜索到。</p>
<p>所以最好集成上。</p>
<p>如果你比较懒，也可以加一个分享apk的功能，也没问题：</p>
<pre><code class="java">#伪代码
public static void shareFile(Context context) &#123;
    File apkFile = AppUtils.getApkFile(context);
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_SEND);
    intent.setType(&quot;*/*&quot;);
    intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(apkFile));
    context.startActivity(intent);
&#125;
</code></pre>
<p>这样就可以将apk分享给别人了。</p>
<p><strong>不是那么容易可触达，就努力变得容易。</strong></p>
<p>很多时候，一些细节，就能给你带来非常多的改善。</p>
<p>当然不仅是app，相信所有你所经历的事情，多观察，多思考，都有很多类似的技巧。</p>
<p>经常思考，努力完善这些细节。</p>
<p>以上就是我做个人app的亲身感悟，希望这些经验可以帮到你！</p>
<p>大家当中应该有比我更有经验的，欢迎留言分享给大家。</p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/12/06/%E4%B8%89%E6%AC%BE%E5%BE%88%E9%85%B7%E5%BE%88%E9%AA%9A%E6%B0%94%E7%9A%84%E5%BA%95%E9%83%A8%E5%AF%BC%E8%88%AA/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          三款很酷很骚气的底部导航
        
      </div>
    </a>
  
  
    <a href="/2020/09/08/Jetpack-Compose-Alpha-%E7%89%88%E7%8E%B0%E5%B7%B2%E5%8F%91%E5%B8%83%EF%BC%81/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Jetpack Compose Alpha 版现已发布！</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=我们要不要上线「个人app」 ？ - ApocalypseBlog&url=http://example.com/2020/10/07/%E6%88%91%E4%BB%AC%E8%A6%81%E4%B8%8D%E8%A6%81%E4%B8%8A%E7%BA%BF%E3%80%8C%E4%B8%AA%E4%BA%BAapp%E3%80%8D-%EF%BC%9F/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=我们要不要上线「个人app」 ？ - ApocalypseBlog&u=http://example.com/2020/10/07/%E6%88%91%E4%BB%AC%E8%A6%81%E4%B8%8D%E8%A6%81%E4%B8%8A%E7%BA%BF%E3%80%8C%E4%B8%AA%E4%BA%BAapp%E3%80%8D-%EF%BC%9F/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=我们要不要上线「个人app」 ？ - ApocalypseBlog&url=http://example.com/2020/10/07/%E6%88%91%E4%BB%AC%E8%A6%81%E4%B8%8D%E8%A6%81%E4%B8%8A%E7%BA%BF%E3%80%8C%E4%B8%AA%E4%BA%BAapp%E3%80%8D-%EF%BC%9F/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>